package com.controller;
import com.entity.AsAccount;
import com.entity.AsKeywords;
import com.entity.AsUser;
import com.entity.MethodLog;
import com.service.AsAccountService;
import com.service.AsFuntionService;
import com.service.AsUserService;
import com.service.RedisService;
import com.utils.AnnotationUtil;
import com.utils.JsonUtil;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.*;

@Controller
public class UserController
{
    @Resource
    private AsUserService asUserService;

    @Resource
    private AsFuntionService asFuntionService;

    @Resource
    private AsAccountService asAccountService;

   /* @Resource
    private RedisService redisService;dddd ada sadafasdsadf
    111
    aaaaa
    222
    bbbb
    3333
    ccccc*/

    //跳转到登陆页面
    @RequestMapping(value = "/toLoginPage")
    public String toLoginPage( Model model )
    {
        model.addAttribute( "asUser" , new AsUser() );
        return "login";
    }

    @RequestMapping("/pre")
    public String toPre()
    {
        return "";
    }

    //将当前验证码存入redis服务器
    @RequestMapping("/saveCodeToRedis")
    public void saveCodeToRedis( HttpSession session )
    {
        //获取当前页面验证码
        String code = (String)session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
        code = code.toLowerCase();
        //将该验证码翻入redis服务器中
       // redisService.saveCodeAndSetTime( code );
    }

    //用户登陆
    @RequestMapping(value = "/dologin")
    @MethodLog(operateInfo = "" )
    public String dologin( @Valid AsUser asUser ,  BindingResult result , String verifyCode , Model model , HttpSession session )
    {
        //从redis服务其中取出验证码
       // String code = redisService.getCode();
        String code = "1234";
        //当前方法名
        String methodName = "dologin";
        //当前方法参数
        Class [] classes = new Class[]{ AsUser.class , BindingResult.class , String.class , Model.class , HttpSession.class };
        AnnotationUtil.setOperateInfo( UserController.class , methodName , "" , classes );
        //数据校验
        //首先查看验证码是否正确
        if( code == null )
        {
            model.addAttribute( "codeError" , "验证码已失效" );
            return "login";
        }
        else
        {
            if( !code.toLowerCase().equals( verifyCode ) )
            {
                model.addAttribute( "codeError" , "验证码不匹配" );
                return "login";
            }
            else
            {
                //验证码匹配后校验用户名密码格式是否匹配
                if( result.hasErrors() )
                {
                    //输入不正确将方法上注解值修改为“”,使之不写入日志
                    return "login";
                }
                else
                {
                    //格式符合后验证用户名和密码是否匹配
                    asUser = asUserService.returnOneUserByNameAndPass( asUser );
                    if( asUser == null )
                    {
                        //用户名密码不正确设置错误信息提示
                        model.addAttribute( "loginError" , "用户名或密码不正确" );
                        return "login";
                    }
                }
            }
        }
        session.setAttribute( "user" , asUser );
        //根据用户查询其对应权限
        //获取所有可用根权限名称
        ArrayList<Map<String,Object>> allRootFuncList = asFuntionService.returnAllAvaliableRootFunctionName();
        //System.out.println( rootFuncList );
        //获取指定用户所有可用子权限
        ArrayList<Map<String,Object>> userAllFuncList = asFuntionService.returnAllAvaliableFunctionNameByRoleId( asUser.getRoleId() );
        //System.out.println( userAllFuncList );
        //创建map key为用户具有的根权限名称 value为map 元素为用户具有的根权限下的子权限名称和对应url
        Map<String,Map<String,String>> userFuncMap = new LinkedHashMap<>();
        //创建集合用于保存用户可访问url(自定义拦截器使用)
        ArrayList<String> userUrlList = new ArrayList<>();
        //迭代所有跟权限名称
        for( Map<String,Object> x : allRootFuncList )
        {
            //创建集合用于保存用户具有的根权限下的子权限名称
            Map<String,String> funcNameAndUrl = new LinkedHashMap<>();
            //获取根权限的id
            int id = (int)x.get( "id" );
            //迭代用户具有的所有子权限
            for( Map<String,Object> y : userAllFuncList )
            {
                //获取子权限id
                int parentId = (int)y.get( "parentId" );
                //若子权限的parentId与根权限id匹配
                //说明用户具有该根权限
                if( id == parentId )
                {
                    //将该子权限和对应url加入map中
                    funcNameAndUrl.put( (String)y.get( "functionName" ) , (String)y.get( "funcUrl" ) );
                    //将url加入集合中(自定义拦截器使用)
                    userUrlList.add( (String)y.get( "funcUrl" ) );
                }
            }
            //将用户对应的根权限和该根权限下的子权限加入map
            if( !funcNameAndUrl.isEmpty() )
            {
                userFuncMap.put( (String)x.get( "functionName" ) , funcNameAndUrl );
            }
        }
        //System.out.println( userFuncMap );
        model.addAttribute( "userFuncMap" , userFuncMap );
        //System.out.println(  userUrlList );
        session.setAttribute( "userUrlList" , userUrlList );
        //获取当前账户余额
        Double money = asAccountService.getMoney( asUser.getId() );
        model.addAttribute( "money" , money );
        //登陆成功修改方法注解值,使之写入日志
        AnnotationUtil.setOperateInfo( UserController.class , methodName , "登陆" , classes );

        return "main";
    }

    //用户退出
    @RequestMapping(value = "/exit")
    public String userExit( HttpSession session )
    {
        session.invalidate();
        return "redirect:/do/toLoginPage";
    }

    //修改用户密码
    @RequestMapping( value = "/updateUserPass" , produces = "application/json;charset=UTF-8")
    @ResponseBody
    @MethodLog( operateInfo = "" )
    public String updateUserPass( @Valid AsUser asUser , BindingResult result , String oldUserPassword, HttpSession session )
    {
        String methodName = "updateUserPass";
        Class [] classes = new Class[]{ AsUser.class , BindingResult.class , String.class , HttpSession.class };
        //获取当前用户
        AsUser user = (AsUser)session.getAttribute( "user" );
        String oldPass = user.getUserPassword();
        Map<String,String> errorMessage = new HashMap<>();
        //校验输入的密码格式是否符合要求，输入的原密码是否一致
        if( !oldPass.equals( oldUserPassword ) )
        {
            errorMessage.put( "oldUserPassword" , "输入的原密码不正确" );
        }
        if( result.hasErrors() )
        {
            for( FieldError error : result.getFieldErrors() )
            {
                errorMessage.put( error.getField() , error.getDefaultMessage() );
            }
        }
        if( !errorMessage.isEmpty() )
        {
            //校验有错改变注解值为空字符串 不记录日志
            AnnotationUtil.setOperateInfo( UserController.class , methodName , "" , classes );
            return JsonUtil.errorMessageJsonStr( errorMessage );
        }
        //校验成功修改用户密码
        asUser.setId( user.getId() );
        Date now = new Date();
        asUser.setLastUpdateTime( now );
        Integer resultCode = asUserService.updateUserPassword( asUser );
        //密码修改成功立即更新当前session中的user
        if( resultCode > 0 )
        {
            session.removeAttribute( "user" );
            user.setUserPassword( asUser.getUserPassword() );
            user.setLastUpdateTime( now  );
            session.setAttribute( "user" , user );
        }
        AnnotationUtil.setOperateInfo( UserController.class , methodName , "修改用户密码" , classes );

        return JsonUtil.successOrNotJsonStr( resultCode );
    }
}
